package cn.dduan.fool.features.optional;


import java.util.Optional;

/**
 * Optional 是用于防范 NullPointerException
 * <p>
 * 总结
 * 1. Optional 提供了一种更优雅的方式来处理可能为 null 的值，避免了显式的 null 检查，并减少了 NullPointerException 的风险。
 * 2. 通过合理使用 Optional 的各种方法，可以使代码更加简洁和易读
 *
 * @author dduan
 * @version 1.0
 * @date 2025/3/6
 */
public class MyOptional {
    public static void main(String[] args) {

    }

    /**
     * 1. 创建 Optional 对象
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void createOptional() {
        // 创建一个包含非空值的 Optional
        Optional<String> optional = Optional.of("Hello");

        // 创建一个可能为空的 Optional
        Optional<String> optionalNullable = Optional.ofNullable(null);

        // 创建一个空的 Optional
        Optional<String> emptyOptional = Optional.empty();
    }

    /**
     * 2. 检查 Optional 是否有值
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void checkOptional() {
        Optional<String> optional = Optional.of("Hello");

        if (optional.isPresent()) {
            System.out.println("Value is present: " + optional.get());
        } else {
            System.out.println("Value is absent");
        }
    }

    /**
     * 3. 如果存在值则执行操作
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void execOptional() {
        Optional<String> optional = Optional.of("Hello");

        optional.ifPresent(value -> System.out.println("Value is present: " + value));
    }

    /**
     * 4. 如果不存在值则使用默认值
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalDefault() {
        Optional<String> optional = Optional.empty();

        String value = optional.orElse("Default Value");
        System.out.println(value); // 输出: Default Value
    }

    /**
     * 5. 如果不存在值则使用 Supplier 提供默认值
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalDefaultSupplier() {
        Optional<String> optional = Optional.empty();

        String value = optional.orElseGet(() -> "Default Value from Supplier");
        System.out.println(value); // 输出: Default Value from Supplier
    }

    /**
     * 6. 如果不存在值则抛出异常
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalThrow() {
        Optional<String> optional = Optional.empty();

        String value = optional.orElseThrow(() -> new IllegalArgumentException("Value is absent"));
    }

    /**
     * 7. 使用 map 转换 Optional 中的值
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalMap() {
        Optional<String> optional = Optional.of("Hello");

        Optional<String> upperCaseOptional = optional.map(String::toUpperCase);
        upperCaseOptional.ifPresent(System.out::println); // 输出: HELLO
    }

    /**
     * 8. 使用 flatMap 扁平化 Optional
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalflatMap() {
        Optional<String> optional = Optional.of("Hello");

        Optional<String> flatMappedOptional = optional.flatMap(value -> Optional.of(value.toUpperCase()));
        flatMappedOptional.ifPresent(System.out::println); // 输出: HELLO
    }

    /**
     * 9. 使用 filter 过滤 Optional 中的值
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalFilter() {
        Optional<String> optional = Optional.of("Hello");

        Optional<String> filteredOptional = optional.filter(value -> value.length() > 5);
        filteredOptional.ifPresent(System.out::println); // 不会输出，因为长度不大于 5
    }

    /**
     * 10. 链式操作
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalChained() {
        Optional<String> optional = Optional.of("Hello");

        optional.map(String::toUpperCase)
                .filter(value -> value.length() > 5)
                .ifPresent(System.out::println); // 不会输出，因为长度不大于 5
    }

    /**
     * 11. 使用 or 提供备选 Optional
     * 注意：Java 9 或者更高版本支持 or()
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalOr() {
        Optional<String> optional = Optional.empty();

        // Optional<String> alternativeOptional = optional.or(() -> Optional.of("Alternative Value"));
        // alternativeOptional.ifPresent(System.out::println); // 输出: Alternative Value
    }

    /**
     * 12. 使用 ifPresentOrElse 处理存在和不存在的情况
     * 注意：Java 9 或者更高版本支持 ifPresentOrElse()
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalIfPresentOrElse() {
        Optional<String> optional = Optional.empty();

        //optional.ifPresentOrElse(
        //        value -> System.out.println("Value is present: " + value),
        //        () -> System.out.println("Value is absent")
        //); // 输出: Value is absent
    }

    /**
     * 13. 使用 stream 将 Optional 转换为 Stream
     * 注意：Java 9 或者更高版本支持 stream()
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalStream() {
        Optional<String> optional = Optional.of("Hello");

        //optional.stream().forEach(System.out::println); // 输出: Hello
    }

    /**
     * 14. 使用 orElseThrow 抛出特定异常
     * 注意：Java 9 或者更高版本支持 stream()
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalOrElseThrow() {
        Optional<String> optional = Optional.empty();

        String value = optional.orElseThrow(() -> new RuntimeException("Value not found"));
    }

    /**
     * 15. 使用 orElseGet 延迟计算默认值
     * 注意：Java 9 或者更高版本支持 stream()
     *
     * @author dduan
     * @version 1.0
     * @date 2025/3/6
     */
    private void optionalOrElseGet() {
        Optional<String> optional = Optional.empty();

        String value = optional.orElseGet(() -> {
            System.out.println("Computing default value");
            return "Default Value";
        });
        System.out.println(value); // 输出: Computing default value \n Default Value
    }
}
